﻿using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Linq;
using System.Web;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
//using System.DirectoryServices.Protocols;
using System.ServiceModel.Security;
using MSXML2;

namespace AppEntity
{
    public partial class Common
    {
        public partial class Utility
        {
            public class RemoteCall
            {
                /// <summary>
                /// 请求类型
                /// </summary>
                public enum RequestType
                {
                    GET,
                    POST,
                    PUT,
                    DELTE
                }
                /// <summary>
                /// 发出请求，不接收响应。
                /// </summary>
                /// <param name="Url">目标地址</param>
                /// <param name="Method">请求方法</param>
                /// <param name="Header">数据包头部</param>
                /// <param name="param">数据实体</param>
                //public static void RequestNoResponse(string Url, RequestType Method, Dictionary<string, string> Header, byte[] param)
                //{                
                //    HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(Url);
                //    rq.Method = Method.ToString();

                //    if (Method ==  RequestType.POST)
                //    {
                //        rq.ContentType = "application/x-www-form-urlencoded";
                //        if (param != null && param.Length > 0)
                //        {
                //            rq.ContentLength = param.Length;
                //            Stream rs = rq.GetRequestStream();
                //            rs.Write(param, 0, param.Length);
                //            rs.Close();
                //        }
                //    }
                //    if (Header != null)
                //    {
                //        foreach (string key in Header.Keys)
                //        {
                //            if (Header[key] == null) continue;
                //            if (key.ToLower() == "cookie")
                //            {
                //                rq.Headers.Add(HttpRequestHeader.Cookie, Header[key]);
                //            }
                //            else
                //            {
                //                rq.Headers.Add(key, Header[key]);
                //            }
                //        }
                //    }
                //}
                ///// <summary>
                ///// 发出请求，不接收响应。
                ///// </summary>
                ///// <param name="Url">目标地址</param>
                ///// <param name="Method">请求方法</param>
                ///// <param name="Header">数据包头部</param>
                ///// <param name="param">数据实体</param>
                //public static void RequestNoResponse(string Url, RequestType Method, Dictionary<string, string> Header, Dictionary<string, string> Param)
                //{
                //    //StringBuilder sb = new StringBuilder();
                //    //foreach (string key in Param.Keys)
                //    //{
                //    //    string value = "";
                //    //    if (Param[key] != null)
                //    //    {
                //    //        value = HttpUtility.UrlEncode(Param[key]);
                //    //    }
                //    //    sb.Append(key + "=" + value + "&");
                //    //}
                //    //string str = sb.ToString();
                //    //if (!string.IsNullOrEmpty(str))
                //    //{
                //    //    str = str.Remove(str.Length - 1);
                //    //}
                //    string str = Param.Select(n => n.Key + "=" + HttpUtility.UrlEncode(n.Value)).ToArray().Join("&");
                //    RequestNoResponse(Url, Method, Header, System.Text.Encoding.UTF8.GetBytes(str));
                //}

                /// <summary>
                /// 发出请求，接收响应。如果采用POST方式，自动设置ContentType=application/x-www-form-urlencoded
                /// </summary>
                /// <param name="Url"></param>
                /// <param name="Method"></param>
                /// <param name="Header">请求数据包的头部，如果键值包含cookie，自动设置cookies</param>
                /// <param name="Bytes">请求数据包的 Body</param>
                /// <returns>返回 HttpWebResponse 对象</returns>            
                public static HttpWebResponse Request(string Url, RequestType Method, Dictionary<string, string> Header, byte[] Bytes)
                {
                    HttpWebRequest rq = null;
                    if (Url.StartsWith("https", System.StringComparison.OrdinalIgnoreCase))
                    {
                        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                        rq = (HttpWebRequest)WebRequest.Create(Url);
                        rq.ProtocolVersion = HttpVersion.Version10;
                    }
                    else
                    {
                        rq = (HttpWebRequest)WebRequest.Create(Url);
                    }
                    rq.Method = Method.ToString();
                    rq.Proxy = null;

                    if (Method == RequestType.POST)
                    {
                        rq.ContentLength = Bytes.Length;
                        rq.ContentType = "application/x-www-form-urlencoded";
                        if (Bytes != null && Bytes.Length > 0)
                        {
                            Stream rs = rq.GetRequestStream();
                            rs.Write(Bytes, 0, Bytes.Length);
                            rs.Flush();
                            rs.Close();
                        }
                    }
                    if (Header != null)
                    {
                        foreach (string key in Header.Keys)
                        {
                            if (Header[key] == null) continue;
                            string LowKey = key.ToLower();
                            if (LowKey.Contains("cookie"))
                            {
                                rq.Headers.Add(HttpRequestHeader.Cookie, Header[key]);
                            }
                            else
                            {
                                rq.Headers.Add(key, Header[key]);
                            }
                        }
                    }
                    return (HttpWebResponse)rq.GetResponse();
                }
                /// <summary>
                /// 发出请求，接收响应。如果采用POST方式，自动设置ContentType=application/x-www-form-urlencoded
                /// </summary>
                /// <param name="Url"></param>
                /// <param name="Method"></param>
                /// <param name="Header"></param>
                /// <param name="NameValue">表单值集合，格式如：name=abc&age=1&sex=male</param>
                /// <returns></returns>
                public static HttpWebResponse Request(string Url, RequestType Method, Dictionary<string, string> Header, string NameValue)
                {
                    return Request(Url, Method, Header, System.Text.Encoding.UTF8.GetBytes(NameValue));
                }

                public static HttpWebResponse Request(string Url, RequestType Method, Dictionary<string, string> Header, Dictionary<string, string> Param)
                {
                    //StringBuilder sb = new StringBuilder();

                    //foreach (string key in Param.Keys)
                    //{
                    //    string value = "";
                    //    if (Param[key] != null)
                    //    {
                    //        value = HttpUtility.UrlEncode(Param[key]);
                    //    }
                    //    sb.Append(key + "=" + value + "&");
                    //}
                    //string str = sb.ToString();
                    //if (!string.IsNullOrEmpty(str) && str.EndsWith("&"))
                    //{
                    //    str = str.Remove(str.Length - 1);
                    //}
                    string str = Param.Select(n => n.Key + "=" + HttpUtility.UrlEncode(n.Value)).ToArray().Join("&");
                    return Request(Url, Method, Header, System.Text.Encoding.UTF8.GetBytes(str));
                }
                public static HttpWebResponse Request(string Url, RequestType Method, Dictionary<string, string> Param)
                {
                    return Request(Url, Method, null, Param);
                }

                public static HttpWebResponse Request(string Url, RequestType Method)
                {
                    return Request(Url, Method, null, new byte[0]);
                }

                ////只提交，不需要返回值
                //public static string RequestUrl(string Url, string Method, Dictionary<string, string> Header, byte[] Param)
                //{
                //    Stream sw = Request(Url, Method, Header, Param).GetResponseStream();
                //    StreamReader sr = new StreamReader(sw, System.Text.Encoding.Default);
                //    string txt = sr.ReadToEnd();
                //    sr.Close();
                //    sw.Close();
                //    return txt;
                //}
                //public static string RequestUrl(string Url, string Method, Dictionary<string, string> Header, string NameValue)
                //{
                //    return RequestUrl(Url, Method, Header, System.Text.Encoding.Default.GetBytes(NameValue));
                //}
                //public static string RequestUrl(string Url, string Method, Dictionary<string, string> Header, Dictionary<string, string> Param)
                //{
                //    StringBuilder sb = new StringBuilder();

                //    foreach (string key in Param.Keys)
                //    {
                //        string value = "";
                //        if (Param[key] != null)
                //        {
                //            value = HttpUtility.UrlEncode(Param[key]);
                //        }
                //        sb.Append(key + "=" + value + "&");
                //    }
                //    string str = sb.ToString();
                //    str = str.Remove(str.Length - 1);

                //    return RequestUrl(Url, Method, Header, System.Text.Encoding.Default.GetBytes(str));
                //}
                //public static string RequestUrl(string Url, string Method, Dictionary<string, string> Param)
                //{
                //    return RequestUrl(Url, Method, null, Param);
                //}
                //public static string RequestUrl(string Url, string Method)
                //{
                //    return RequestUrl(Url, Method, null, new byte[0]);
                //}

                private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                {
                    return true; //总是接受
                }


                public class XmlHttpResponse
                {
                    public Dictionary<string, string> Headers = null;
                    public string Text = null;
                    public byte[] Bytes = null;
                }
                /// <summary>
                /// 使用 ServerXMLHTTP60 对象发送请求。
                /// </summary>
                /// <param name="Url"></param>
                /// <param name="Method"></param>
                /// <param name="Headers"></param>
                /// <param name="Param"></param>
                /// <returns></returns>
                public static XmlHttpResponse XmlHttpRequest(string Url, RequestType Method, Dictionary<string, string> Headers, Dictionary<string, string> Param)
                {
                    ServerXMLHTTP60 Server = new ServerXMLHTTP60();
                    Server.setTimeouts(60000, 60000, 60000, 60000);
                    Server.open(Method.ToString(), Url, false, null, null);
                    if (Headers != null)
                    {
                        foreach (string key in Headers.Keys)
                        {
                            string val = "";
                            if (Headers[key] != null)
                            {
                                val = Headers[key].ToString();
                            }
                            Server.setRequestHeader(key, val);
                        }
                    }
                    if (Method.ToString() == "POST")
                    {
                        Server.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    }
                    string[] arr = new string[Param.Count];
                    int counter = 0;
                    if (Param != null)
                    {
                        foreach (string key in Param.Keys)
                        {
                            string val = "";
                            if (Param[key] != null)
                            {
                                val = HttpUtility.UrlEncode(Param[key].ToString());
                            }
                            arr[counter] = key + "=" + val;
                            counter++;
                        }
                    }
                    Server.send(counter > 0 ? string.Join("&", arr) : null);

                    Dictionary<string, string> HeadersDict = null;
                    string Header = Server.getAllResponseHeaders();
                    if (!string.IsNullOrEmpty(Header))
                    {
                        HeadersDict = new Dictionary<string, string>();
                        string[] HeadersArr = Server.getAllResponseHeaders().Split(new char[] { '\r', '\n' });
                        foreach (string Line in HeadersArr)
                        {
                            if (!Line.Contains(":")) continue;
                            string[] Keys = Line.Split(':');
                            HeadersDict.Add(Keys[0], Keys[1].Trim());
                        }
                    }
                    XmlHttpResponse Result = new XmlHttpResponse() { Headers = HeadersDict, Text = Server.responseText, Bytes = (byte[])Server.responseBody };
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(Server);

                    return Result;
                }

                public static XmlHttpResponse XmlHttpRequest(string Url, RequestType Method, Dictionary<string, string> Headers, byte[] Bytes)
                {
                    ServerXMLHTTP60 Server = new ServerXMLHTTP60();
                    Server.setTimeouts(60000, 60000, 60000, 60000);
                    Server.open(Method.ToString(), Url, false, null, null);
                    if (Headers != null)
                    {
                        foreach (string key in Headers.Keys)
                        {
                            string val = "";
                            if (Headers[key] != null)
                            {
                                val = Headers[key].ToString();
                            }
                            Server.setRequestHeader(key, val);
                        }
                    }
                    if (Method.ToString() == "POST")
                    {
                        Server.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    }

                    if (Bytes != null && Bytes.Length > 0)
                    {
                        Server.send(Bytes);
                    }
                    else
                    {
                        Server.send(null);
                    }


                    Dictionary<string, string> HeadersDict = null;
                    string Header = Server.getAllResponseHeaders();
                    if (!string.IsNullOrEmpty(Header))
                    {
                        HeadersDict = new Dictionary<string, string>();
                        string[] HeadersArr = Header.Split(new char[] { '\r', '\n' });
                        foreach (string Line in HeadersArr)
                        {
                            string lineTxt = Line.Trim();
                            if (!lineTxt.Contains(":"))
                            {
                                if (!HeadersDict.ContainsKey(lineTxt))
                                {
                                    HeadersDict.Add(lineTxt, "");
                                }
                            }
                            else
                            {
                                string[] Keys = lineTxt.Split(':');
                                HeadersDict.Add(Keys[0], Keys[1].Trim());
                            }
                        }
                    }
                    XmlHttpResponse Result = new XmlHttpResponse() { Headers = HeadersDict, Text = Server.responseText, Bytes = (byte[])Server.responseBody };
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(Server);

                    return Result;
                }
            }
        }
    }
}
